// game.hpp
//

#ifndef _GAME_HPP
#define _GAME_HPP

#include "base.hpp"
#include "node.hpp"
#include "ncamera.hpp"
#include "model.hpp"
#include "map.hpp"



// Game
//
class Game
{
public:
  Game ();
  
  Node &get_scene () { return scene; }
  NDataCamera *get_camera ( int n );
  
  void init ();
  void update ( double dtime );
  
private:
  void init_models ();
  void init_cameras ();
  void init_lights ();
  void init_map ();
  void update_cameras ( double game_time,
                        double dtime );
  void update_lights ( double game_time,
                       double dtime );
  void update_entities ( double game_time,
                         double dtime );
  
  static const std::string datadir;

  Map map{};
  
  Model mod_cube{};
  Model mod_sphere{};
  Model mod_axis{};
  Model mod_camera{};
  Model mod_suzanne{};
  Model mod_map{};
  Model mod_map_grid{};
  Model mod_map_normals{};
  Model mod_normals_test{};
  
  wgl::Material mat_unlit_white
    {
      { 1.f, 1.f, 1.f, 1.f },
      {},
      {},
      0.f,
    };

  wgl::Material mat_light_1
    {
      { 1.f, 1.f, 1.f, 1.f },
      {},
      {},
      0.f,
    };

  wgl::Material mat_light_2
    {
      { 1.f, 1.f, 1.f, 1.f },
      {},
      {},
      0.f,
    };
  
  wgl::Material mat_white
    {
      { 1.f, 1.f, 1.f, 1.f },
      { 1.f, 1.f, 1.f, 1.f },
      { 1.f, 1.f, 1.f, 1.f },
      32.f,
    };

  wgl::Material mat_emerald
    {
      { .0215f, .1745f, .0215f, 1.f },
      { .0757f, .6142f, .0756f, 1.f },
      { .6330f, .7278f, .6330f, 1.f },
      .6f * 128.f,
    };

  wgl::Material mat_jade
    {
      { .1350f, .2225f, .1575f, 1.f },
      { .5400f, .8900f, .6300f, 1.f },
      { .3162f, .3162f, .3162f, 1.f },
      .1f * 128.f,
    };

  wgl::Material mat_obsidian
    {
      { .0538f, .0500f, .0662f, 1.f },
      { .1828f, .1700f, .2253f, 1.f },
      { .3327f, .3286f, .3464f, 1.f },
      .3f * 128.f,
    };
  
  Texture tex_cobble{datadir + "/textures/default_cobble.png"};
  Texture tex_grass{datadir + "/textures/default_grass.png"};
  Texture tex_brick{datadir + "/textures/default_stone_brick.png"};
  Texture tex_wood{datadir + "/textures/default_wood.png"};
  Texture tex_sandstone{datadir + "/textures/default_silver_sandstone.png"};
  Texture tex_steel{datadir + "/textures/default_steel_block.png"};
  
  NDataScene d_scene{};
  Node scene{d_scene};
  
  NDataCamera d_camera_0{};
  Node camera_0{d_camera_0, &scene};
  
  NDataCamera d_camera_1{};
  Node camera_1{d_camera_1, &scene};

  NDataLight d_light_1{};
  Node light_1{d_light_1, &scene};

  NDataLight d_light_2{};
  Node light_2{d_light_2, &scene};

  NDataEntity d_light_obj_1{mod_sphere, mat_light_1, /* [temp] */ tex_sandstone, ENTITY_LIGHT_SOURCE};
  Node light_obj_1{d_light_obj_1, &scene};
  
  NDataEntity d_light_obj_2{mod_sphere, mat_light_2, /* [temp] */ tex_sandstone, ENTITY_LIGHT_SOURCE};
  Node light_obj_2{d_light_obj_2, &scene};
  
  NDataEntity d_axis{mod_axis, mat_unlit_white, /* [temp] */ tex_sandstone, ENTITY_MARKER};
  Node axis{d_axis, &scene};

  NDataEntity d_cam_marker{mod_camera, ENTITY_MARKER};
  Node cam_marker{d_cam_marker, &scene};
  
  NDataEntity d_obj_1{mod_cube, mat_emerald, tex_sandstone, ENTITY_OBJECT};
  Node obj_1{d_obj_1, &scene};
  
  NDataEntity d_obj_2{mod_suzanne, mat_jade, tex_sandstone, ENTITY_OBJECT};
  Node obj_2{d_obj_2, &scene};
  
  NDataEntity d_obj_3{mod_sphere, mat_obsidian, tex_sandstone, ENTITY_OBJECT};
  Node obj_3{d_obj_3, &scene};

  NDataEntity d_map{mod_map, mat_white, tex_grass, ENTITY_OBJECT};
  Node node_map{d_map, &scene};

  NDataEntity d_map_grid{mod_map_grid, mat_jade, tex_sandstone, ENTITY_MARKER};
  Node node_map_grid{d_map_grid, &scene};

  NDataEntity d_map_normals{mod_map_normals, mat_white, tex_sandstone, ENTITY_MARKER};
  Node node_map_normals{d_map_normals, &scene};

  // testing
  NDataEntity d_normals_test{mod_normals_test, mat_unlit_white, tex_sandstone, ENTITY_MARKER};
  Node normals_test{d_normals_test, &scene};
  NDataEntity &normals_target{d_obj_2};
};

inline const std::string Game::datadir{DATADIR};



#endif
